﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using AMM.Business;
using AMM.Business.Project;
using AMM.Business.Store;
using AMM.CustomClassLibrary;
using AMM.CustomWinComponents.Validator;
using AMM.Model;
using AMM.Model.Project;
using AMM.Model.Store;

namespace AMM.UserControls {
    public partial class SuspenseOrderEditControl : BaseEditControl {

        private FlexBindingSource<SuspenseOrder> _fbs;
        private ProcurementOrderProcessor _procurementOrderProcessor;
        private SuspenseOrderProcessor _suspenseOrderProcessor;

        public override object BaseEditModel {
            get {
                this._fbs.CurrentItem.SuspenseOrderDetails =
                    this.dgvMaterialEdit.GetDataSourceEx<SuspenseOrderDetail>(this._fbs.CurrentItem.ClassStatus != ClassStatus.Added);
                return this._fbs.CurrentItem;
            }
            set {
                if (this._fbs == null) { this._fbs = new FlexBindingSource<SuspenseOrder>(); }
                this._fbs.CurrentItem = (SuspenseOrder)value;
            }
        }

        public SuspenseOrderEditControl() {
            this.InitializeComponent();
        }

        private void BindMaterial(int procurementId) {
            MaterialProcessor materialProcessor = new MaterialProcessor(int.MaxValue);
            List<MaterialViewModel> materialList = materialProcessor.FetchMaterialViewModelListByProcumentOrderId(procurementId);
            //if (procurementId == 0) {
            //    MaterialSearchModel searchModel = new MaterialSearchModel() { IsEnabled = true };
            //    materialList = materialProcessor.FetchMaterialViewModelList(searchModel);
            //}
            //else {
            //    materialList = materialProcessor.FetchMaterialViewModelListByProcumentOrderId(procurementId);
            //}

            this.Material.DisplayMemberEx = "Code";
            this.Material.ValueMemberEx = "Key";
            this.Material.HeightEx = 300;
            this.Material.WidthEx = 400;
            this.Material.PageSizeEx = 20;
            this.Material.DataBind(new MaterialViewModel(), x => new { x.MaterialType, x.Code, x.Name, x.Remarks }, materialList);
        }

        private void BindProcurement(int procurementOrderId = 0) {
            ProcurementOrderSearchModel searchModel = new ProcurementOrderSearchModel() { OrderStatus = 2, DeliverStatus = 4 };
            ProcurementOrderProcessor procurementOrderProcessor = new ProcurementOrderProcessor(int.MaxValue);
            List<ProcurementOrderViewModel> procurementOrderList = procurementOrderProcessor.FetchProcurementOrderViewModelList(searchModel);
            if (procurementOrderId != 0 && !procurementOrderList.Any(x => x.Key == procurementOrderId)) {
                ProcurementOrder procurementOrder = procurementOrderProcessor.FetchProcurementOrderById(procurementOrderId);
                procurementOrderList.Add(new ProcurementOrderViewModel() {
                    Key = procurementOrder.ProcurementOrderId,
                    Code = procurementOrder.Code
                });
            }

            procurementOrderList.ForEach(x => {
                ProcurementOrder procurementOrder = procurementOrderProcessor.FetchProcurementOrderById(x.Key);
                List<SuspenseOrderDetail> suspenseOrderDetailList = this._suspenseOrderProcessor.FetchSuspenseOrderDetailList(x.Key);
                if (suspenseOrderDetailList.Count == 0 ||
                    procurementOrder.ProcurementOrderDetails.Any(y => suspenseOrderDetailList
                        .Where(z => z.MaterialId == y.MaterialId)
                        .Sum(z => z.SuspenseQuantity) <= y.Quantity)) {
                    x.CreatedBy = "Need";
                }
            });

            this.ddlProcurement.DisplayMemberEx = "Code";
            this.ddlProcurement.ValueMemberEx = "Key";
            this.ddlProcurement.HeightEx = 300;
            this.ddlProcurement.WidthEx = 400;
            this.ddlProcurement.PageSizeEx = 20;
            this.ddlProcurement.DataBind(new ProcurementOrderViewModel(), x => new {
                x.Code,
                x.VendorCode,
                x.VendorName
            }, procurementOrderList.Where(x => x.CreatedBy == "Need").ToList());
        }

        private void CreateFormBindings() {
            this._fbs.CreateBinding(this.ddlProcurement, x => x.SelectedValueEx, y => y.ProcurementOrderId);
            this._fbs.CreateBinding(this.tbCode, x => x.Text, y => y.Code);
            this._fbs.CreateBinding(this.tbRemarks, x => x.Text, y => y.Remarks);
            this._fbs.CreateBinding(this.tbDeliveryOrderCode, x => x.Text, y => y.DeliveryOrderCode);
        }

        private void BindValidation() {
            this.ValidatorForEdit.SetType(this.tbCode, ValidationType.Required | ValidationType.RegularExpression);
            this.ValidatorForEdit.SetRequiredMessage(this.tbCode, this.RequiredMessage);
            this.ValidatorForEdit.SetRegularExpression(this.tbCode, "^[A-Za-z0-9-]+$");
            this.ValidatorForEdit.SetRegularExpressionMessage(this.tbCode, "编码只能由字母，数字，连接线组成");

            this.ValidatorForEdit.SetType(this.ddlProcurement, ValidationType.Required);
            this.ValidatorForEdit.SetRequiredMessage(this.ddlProcurement, this.RequiredMessage);
        }

        private void SuspenseEditControl_Load(object sender, EventArgs e) {
            if (this._fbs == null) { this._fbs = new FlexBindingSource<SuspenseOrder>(); }
            this._procurementOrderProcessor = new ProcurementOrderProcessor();
            this._suspenseOrderProcessor = new SuspenseOrderProcessor();

            this.BindMaterial(this._fbs.CurrentItem.ProcurementOrderId);
            this.BindProcurement(this._fbs.CurrentItem.ProcurementOrderId);
            this.dgvMaterialEdit.DataSourceEx = this._fbs.CurrentItem.SuspenseOrderDetails.ToList();
            this.CreateFormBindings();
            this.BindValidation();

            this.ddlProcurement.Enabled = false;
            if (this._fbs.CurrentItem.ClassStatus == ClassStatus.Added) {
                string autoCode = CommonHelper.GenerateAutoCode("S");
                int maxNumber = new SuspenseOrderProcessor().GetTheMaxFlowNumber(autoCode);
                this._fbs.CurrentItem.Code = CommonHelper.GendrateSpecificCode(autoCode, maxNumber);
                this.ddlProcurement.Enabled = true;
            }
        }

        private void ddlProcurement_ValueChanged(object sender, EventArgs e) {
            if (this.ddlProcurement.SelectedValueEx == null) { return; }
            if (this._fbs.CurrentItem.ClassStatus == ClassStatus.Updated) { return; }
            int procurementId = Convert.ToInt32(this.ddlProcurement.SelectedValueEx);
            this.BindMaterial(procurementId);

            ProcurementOrder procurementOrder = this._procurementOrderProcessor.FetchProcurementOrderById(procurementId);
            List<SuspenseOrderDetail> suspenseOrderDetailList = this._suspenseOrderProcessor.FetchSuspenseOrderDetailList(procurementId);
            this._fbs.CurrentItem.SuspenseOrderDetails.Clear();
            procurementOrder.ProcurementOrderDetails.ToList().ForEach(x => {
                decimal suspensedQuantity = suspenseOrderDetailList
                    .Where(y => y.MaterialId == x.MaterialId)
                    .Sum(y => y.SuspenseQuantity);

                if (suspensedQuantity == 0 || suspensedQuantity < x.Quantity) {
                    this._fbs.CurrentItem.SuspenseOrderDetails.Add(new SuspenseOrderDetail() {
                        MaterialId = x.MaterialId,
                        ProcurementQuantity = x.Quantity - suspensedQuantity,
                        SuspenseQuantity = x.Quantity - suspensedQuantity,
                        SuspenseDate = DateTime.Now
                    });
                }
            });
            this.dgvMaterialEdit.DataSourceEx = this._fbs.CurrentItem.SuspenseOrderDetails.ToList();
        }

        private void dgvMaterialEdit_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
            if (this.dgvMaterialEdit.Columns[e.ColumnIndex].Name == "SuspenseQuantity") {
                decimal pqValue = Convert.ToDecimal(this.dgvMaterialEdit["ProcurementQuantity", e.RowIndex].Value);
                decimal sqvalue = Convert.ToDecimal(this.dgvMaterialEdit[e.ColumnIndex, e.RowIndex].Value);
                this.dgvMaterialEdit.Rows[e.RowIndex].Cells["ErrMessage"].Value = sqvalue > pqValue ? "暂收数量不能大于剩余采购量" : string.Empty;
            }
        }
    }
}
